'''
Created on Dec 7, 2012

@author: laura
'''

import sys
import shlex
import subprocess
import string

def runApacheBench(time, concurrency, outputFile, url):
    command = "ab -k -c " + str(concurrency) + " -t " + str(time) + " -g " + outputFile + " " + url
    print "running " + command
    
    p = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
    if p.wait() != 0:
        raise RuntimeError("Errors running ", command)
    else:
        for i in p.stdout.readlines():
            if "Non-2xx" in i or "Failed" in i:
                print i.strip()

def computeGnuplotStats(dataIn, dataOut, duration):
    ''' read in the data in dataIn, format like this:
    starttime    seconds    ctime    dtime    ttime    wait
    Fri Dec 07 14:26:48 2012    1354890408    0    0    0    0
    Write out in a more digestible gnuplot format like this
    timeSinceTestStart qps 50percentile 90percentile 99percentile'''
    avgPerSecond = [0.0] * duration
    # would be nice to support these but the computation is a bit more fiddly
    #p90PerSecond = [0.0] * duration
    #p99PerSecond = [0.0] * duration
    maxPerSecond = [0.0] * duration
    firstSec= None
    txPerSecond = [0] * duration
    
    input = open(dataIn, "r")
    first = True
    for line in input.readlines():
        if(first):
            first = False
        else:
            fields = string.split(line, "\t")
            seconds = int(fields[1])
            ttime = int(fields[4])
            if(firstSec == None):
                firstSec = seconds
            seconds = seconds - firstSec
            if(ttime > maxPerSecond[seconds]):
                maxPerSecond[seconds] = ttime
            txPerSecond[seconds] += 1 
            avgPerSecond[seconds] = avgPerSecond[seconds] + (ttime-avgPerSecond[seconds])/txPerSecond[seconds]

    output = open(dataOut, "w")
    for i in range(0, duration-1):
        output.write(str(i) + " " + str(txPerSecond[i]) + " " + str(avgPerSecond[i]) + " " 
                     + str(maxPerSecond[i]) + "\n")
    output.close()
    
def runGnuPlot(dataIn, sC, eC, iC, dataOut, desc, url, field, yaxis):
    gnuplotScript = open("tmp/tmp.gp" + str(field-1), "w")

    gnuplotScript.write("set terminal png\n")
    gnuplotScript.write("set output \"" + dataOut + "\"\n")
    gnuplotScript.write("set title \"Performance for " + url + "\"\n")

    gnuplotScript.write("set size 1,0.7\n")
    gnuplotScript.write("set xlabel \"Time\"\n")
    gnuplotScript.write("set ylabel \"" + yaxis +"\n\n")
    
    first = True
    last = False
    c = sC
    i = 0
    while (c <= eC):
        if(c == eC):
            last = True
        
        if(first == True):
            gnuplotScript.write("plot")
            first = False
        
        gnuplotScript.write(" \"" + dataDir + "/conc" + str(c) + ".dat\" using 1:" + str(field) + " with lines title \"" + desc +"conc" + str(c) + "\"")
        
        if(last == True):
            gnuplotScript.write("\n")                      
        else:
            gnuplotScript.write(", \\")
            gnuplotScript.write("\n")
        c += iC
        i += 1

if __name__ == '__main__':
    if(len(sys.argv) != 10):
        print "Usage: runloadtest URL duration startC endC incC dataDir outputGraphTPS outputGraphAvg outputGraphMax"
        sys.exit(1)
        
    url = sys.argv[1]
    duration = int(sys.argv[2])
    startC = int(sys.argv[3])
    endC = int(sys.argv[4])
    incC = int(sys.argv[5])
    dataDir = sys.argv[6]
    outputGraph1 = sys.argv[7]    
    outputGraph2 = sys.argv[8] 
    outputGraph3 = sys.argv[9]  
    
    c = startC
    while(c <= endC):
        runApacheBench(duration, c, dataDir + "/conc" + str(c), url)
        computeGnuplotStats(dataDir + "/conc" + str(c), dataDir + "/conc" + str(c) + ".dat", duration+2)
        c += incC
        
    runGnuPlot(dataDir, startC, endC, incC, outputGraph1, "tps",  url, 2, "Txn per second")
    runGnuPlot(dataDir, startC, endC, incC, outputGraph2, "avg",  url, 3, "Average response time")
    runGnuPlot(dataDir, startC, endC, incC, outputGraph3, "max",  url, 4, "Max response time")
    